/*
 *------------------------------------------------------------------------------
 * @File      :    gc0308_dvp.c
 * @Date      :    2021-3-20
 * @Author    :    lomboswer <lomboswer@lombotech.com>
 * @Brief     :    Source file for MDP(Media Development Platform).
 *
 * Copyright (C) 2020-2021, LomboTech Co.Ltd. All rights reserved.
 *------------------------------------------------------------------------------
 */
#include "ei_comm_camera.h"
#include "camera_usr.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */

#define SNS_ID 308
#define SNS_NAME  "gc0308_dvp"
#define DEV_TYPE DVP

static SNS_STATE_S g_sastSns[VISS_MAX_DEV_NUM];

static const SNS_REG_S s_aInitRegList[] = {
    /* PCLK  24M 30fps */
    {0xfe, 0x80},
    {0xfe, 0x00},	/* set page0 */
    {0xd2, 0x10},	/* close AEC */
    {0x22, 0x55},	/* close AWB */

    {0x03, 0x01},
    {0x04, 0x2c},
    {0x5a, 0x56},
    {0x5b, 0x40},
    {0x5c, 0x4a},

    {0x22, 0x57},	/* Open AWB */

    {0x01, 0x6a},
    {0x02, 0x0c},
    {0x0f, 0x00},

    {0xe2, 0x00},	/* anti-flicker step [11:8] */
    {0xe3, 0x96},	/* anti-flicker step [7:0] */

    {0xe4, 0x01},	/* exp level 1  16.67fps */
    {0xe5, 0xc2},
    {0xe6, 0x01},	/* exp level 2  12.5fps */
    {0xe7, 0xc2},
    {0xe8, 0x01},	/* exp level 3  8.33fps */
    {0xe9, 0xc2},
    {0xea, 0x01},	/* exp level 4  4.00fps */
    {0xeb, 0xc2},

    {0xec, 0x30},

    {0x05, 0x00},
    {0x06, 0x00},
    {0x07, 0x00},
    {0x08, 0x00},
    {0x09, 0x01},
    {0x0a, 0xe8},
    {0x0b, 0x02},
    {0x0c, 0x88},
    {0x0d, 0x02},
    {0x0e, 0x02},
    {0x10, 0x22},
    {0x11, 0xfd},
    {0x12, 0x2a},
    {0x13, 0x00},

    {0x15, 0x0a},
    {0x16, 0x05},
    {0x17, 0x01},
    {0x18, 0x44},
    {0x19, 0x44},
    {0x1a, 0x1e},
    {0x1b, 0x00},
    {0x1c, 0xc1},
    {0x1d, 0x08},
    {0x1e, 0x60},
    {0x1f, 0x3F},

    {0x20, 0xff},
    {0x21, 0xf8},
    {0x22, 0x57},
    {0x24, 0xa0},	/* 0=uyvy;1=vyuy;2=yuyv;3=yvyu */
    {0x25, 0x0f},

    /* outut sync_mode */
    {0x26, 0x02},	/* modefy by tbl 20191206  default 0x03 */

    {0x2f, 0x01},
    {0x30, 0xf7},
    {0x31, 0x50},
    {0x32, 0x00},
    {0x39, 0x04},
    {0x3a, 0x18},
    {0x3b, 0x20},
    {0x3c, 0x00},
    {0x3d, 0x00},
    {0x3e, 0x00},
    {0x3f, 0x00},
    {0x50, 0x10},
    {0x53, 0x82},
    {0x54, 0x80},
    {0x55, 0x80},
    {0x56, 0x82},
    {0x8b, 0x40},
    {0x8c, 0x40},
    {0x8d, 0x40},
    {0x8e, 0x2e},
    {0x8f, 0x2e},
    {0x90, 0x2e},
    {0x91, 0x3c},
    {0x92, 0x50},
    {0x5d, 0x12},
    {0x5e, 0x1a},
    {0x5f, 0x24},
    {0x60, 0x07},
    {0x61, 0x15},
    {0x62, 0x08},
    {0x64, 0x03},
    {0x66, 0xe8},
    {0x67, 0x86},
    {0x68, 0xa2},
    {0x69, 0x18},
    {0x6a, 0x0f},
    {0x6b, 0x00},
    {0x6c, 0x5f},
    {0x6d, 0x8f},
    {0x6e, 0x55},
    {0x6f, 0x38},
    {0x70, 0x15},
    {0x71, 0x33},
    {0x72, 0xdc},
    {0x73, 0x80},
    {0x74, 0x02},
    {0x75, 0x3f},
    {0x76, 0x02},
    {0x77, 0x36},
    {0x78, 0x88},
    {0x79, 0x81},
    {0x7a, 0x81},
    {0x7b, 0x22},
    {0x7c, 0xff},
    {0x93, 0x48},
    {0x94, 0x00},
    {0x95, 0x05},
    {0x96, 0xe8},
    {0x97, 0x40},
    {0x98, 0xf0},
    {0xb1, 0x38},
    {0xb2, 0x38},
    {0xbd, 0x38},
    {0xbe, 0x36},
    {0xd0, 0xc9},
    {0xd1, 0x10},
    {0xd3, 0x80},
    {0xd5, 0xf2},
    {0xd6, 0x16},
    {0xdb, 0x92},
    {0xdc, 0xa5},
    {0xdf, 0x23},
    {0xd9, 0x00},
    {0xda, 0x00},
    {0xe0, 0x09},

    {0xed, 0x04},
    {0xee, 0xa0},
    {0xef, 0x40},
    {0x80, 0x03},
    {0x80, 0x03},
    {0x9F, 0x10},
    {0xA0, 0x20},
    {0xA1, 0x38},
    {0xA2, 0x4E},
    {0xA3, 0x63},
    {0xA4, 0x76},
    {0xA5, 0x87},
    {0xA6, 0xA2},
    {0xA7, 0xB8},
    {0xA8, 0xCA},
    {0xA9, 0xD8},
    {0xAA, 0xE3},
    {0xAB, 0xEB},
    {0xAC, 0xF0},
    {0xAD, 0xF8},
    {0xAE, 0xFD},
    {0xAF, 0xFF},
    {0xc0, 0x00},
    {0xc1, 0x10},
    {0xc2, 0x1C},
    {0xc3, 0x30},
    {0xc4, 0x43},
    {0xc5, 0x54},
    {0xc6, 0x65},
    {0xc7, 0x75},
    {0xc8, 0x93},
    {0xc9, 0xB0},
    {0xca, 0xCB},
    {0xcb, 0xE6},
    {0xcc, 0xFF},
    {0xf0, 0x02},
    {0xf1, 0x01},
    {0xf2, 0x01},
    {0xf3, 0x30},
    {0xf9, 0x9f},
    {0xfa, 0x78},

    {0xfe, 0x01},/* set page1 */
    {0x00, 0xf5},
    {0x02, 0x1a},
    {0x0a, 0xa0},
    {0x0b, 0x60},
    {0x0c, 0x08},
    {0x0e, 0x4c},
    {0x0f, 0x39},
    {0x11, 0x3f},
    {0x12, 0x72},
    {0x13, 0x13},
    {0x14, 0x42},
    {0x15, 0x43},
    {0x16, 0xc2},
    {0x17, 0xa8},
    {0x18, 0x18},
    {0x19, 0x40},
    {0x1a, 0xd0},
    {0x1b, 0xf5},
    {0x70, 0x40},
    {0x71, 0x58},
    {0x72, 0x30},
    {0x73, 0x48},
    {0x74, 0x20},
    {0x75, 0x60},
    {0x77, 0x20},
    {0x78, 0x32},
    {0x30, 0x03},
    {0x31, 0x40},
    {0x32, 0xe0},
    {0x33, 0xe0},
    {0x34, 0xe0},
    {0x35, 0xb0},
    {0x36, 0xc0},
    {0x37, 0xc0},
    {0x38, 0x04},
    {0x39, 0x09},
    {0x3a, 0x12},
    {0x3b, 0x1C},
    {0x3c, 0x28},
    {0x3d, 0x31},
    {0x3e, 0x44},
    {0x3f, 0x57},
    {0x40, 0x6C},
    {0x41, 0x81},
    {0x42, 0x94},
    {0x43, 0xA7},
    {0x44, 0xB8},
    {0x45, 0xD6},
    {0x46, 0xEE},
    {0x47, 0x0d},

    {0xfe, 0x00}, /* set page0 */
    {0xd2, 0x90},


    /*-----------Update the registers 2010/07/06-------------*/
    /* Registers of Page0 */
    {0xfe, 0x00}, /* set page0 */
    {0x10, 0x26},
    {0x11, 0x0d},  /* fd,modified by mormo 2010/07/06 */
    {0x1a, 0x2a},  /* 1e,modified by mormo 2010/07/06 */

    {0x1c, 0x49}, /* c1,modified by mormo 2010/07/06 */
    {0x1d, 0x9a}, /* 08,modified by mormo 2010/07/06 */
    {0x1e, 0x61}, /* 60,modified by mormo 2010/07/06 */

    {0x3a, 0x20},

    {0x50, 0x14},  /* 10,modified by mormo 2010/07/06 */
    {0x53, 0x80},
    {0x56, 0x80},

    {0x8b, 0x20}, /* LSC */
    {0x8c, 0x20},
    {0x8d, 0x20},
    {0x8e, 0x14},
    {0x8f, 0x10},
    {0x90, 0x14},

    {0x94, 0x02},
    {0x95, 0x07},
    {0x96, 0xe0},

    {0xb1, 0x40}, /* YCPT */
    {0xb2, 0x40},
    {0xb3, 0x40},
    {0xb6, 0xe0},

    {0xd0, 0xcb}, /* AECT  c9,modifed by mormo 2010/07/06 */
    {0xd3, 0x48}, /* 80,modified by mormor 2010/07/06 */

    {0xf2, 0x02},
    {0xf7, 0x12},
    {0xf8, 0x0a},

    /* Registers of Page1 */
    {0xfe, 0x01},/* set page1 */
    {0x02, 0x20},
    {0x04, 0x10},
    {0x05, 0x08},
    {0x06, 0x20},
    {0x08, 0x0a},

    {0x0e, 0x44},
    {0x0f, 0x32},
    {0x10, 0x41},
    {0x11, 0x37},
    {0x12, 0x22},
    {0x13, 0x19},
    {0x14, 0x44},
    {0x15, 0x44},

    {0x19, 0x50},
    {0x1a, 0xd8},

    {0x32, 0x10},

    {0x35, 0x00},
    {0x36, 0x80},
    {0x37, 0x00},
    /*-----------Update the registers end---------*/
    {0xfe, 0x00},/* set page0 */

    /*-----------GAMMA Select(2)---------------*/
    {0x9F, 0x0E},
    {0xA0, 0x1C},
    {0xA1, 0x34},
    {0xA2, 0x48},
    {0xA3, 0x5A},
    {0xA4, 0x6B},
    {0xA5, 0x7B},
    {0xA6, 0x95},
    {0xA7, 0xAB},
    {0xA8, 0xBF},
    {0xA9, 0xCE},
    {0xAA, 0xD9},
    {0xAB, 0xE4},
    {0xAC, 0xEC},
    {0xAD, 0xF7},
    {0xAE, 0xFD},
    {0xAF, 0xFF},

    /*-----------GAMMA Select End--------------*/

    /*-------------H_V_Switch(4)---------------*/
    {0xfe, 0x00},
    {0x14, 0x13},

    {0xff, 0xff},
};

static CAMERA_POWER_ACT_S s_stPowerUpAct[] = {
    {SNS_RESET, SNS_DOWN},
    {SNS_DELAY, 10},
    {SNS_RESET, SNS_UP},
    {SNS_DELAY, 10},
};

static CAMERA_POWER_ACT_S s_sPowerDownAct[] = {
    {SNS_RESET, SNS_DOWN},
    {SNS_DELAY, 10},
};

static SNS_TYPE_ATTR_S s_astSnsAttr[] = {
    {
        .enSnsType                  = GC0308_DVP_1920_1080_30FPS_RAW12,
        .enPixelFormat              = PIX_FMT_YUYV_PACKAGE_422,
        .stSize                     = {640, 480},
        .u32Mclock                  = 24000000,

        .u32Left                    = 0,
        .u32Top                     = 0,

        .u32FrameRate                = 30,
        .astRegCfgs[0].pstRegs      = s_aInitRegList,
        .astRegCfgs[0].u32RegsCnt   = ARRAY_SIZE(s_aInitRegList),
    },
};

static int CAMERA_SetI2cInfo(VISS_DEV dev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    if (pstSnsState->stI2cInfo.fd > 0) {
        return EI_SUCCESS;
    }

    pstSnsState->stI2cInfo.u8RegBits = 8;
    pstSnsState->stI2cInfo.u8ValBits = 8;
    pstSnsState->stI2cInfo.u16I2cBusNum = 2;
    pstSnsState->stI2cInfo.u16I2cDevAddr = 0x21;
    pstSnsState->pcName = SNS_NAME;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_Detect(VISS_DEV VissDev)
{

    EI_U8 u8Tmp;
    EI_S32 s32Ret = EI_SUCCESS;
    SNS_STATE_S *pstSnsState = EI_NULL;
    I2C_INFO_S *pstI2cInfo = EI_NULL;

    SNS_GET_CTX(VissDev, pstSnsState);

    pstI2cInfo = &pstSnsState->stI2cInfo;

    CAMERA_CHECK_POINTER(pstI2cInfo->pfnReadReg);
    s32Ret = pstI2cInfo->pfnReadReg(pstSnsState, 0x00, &u8Tmp);
    if (s32Ret != 0) {
        PRT_VISS_ERR("tmp=%x\n", u8Tmp);
        return EI_FAILURE;
    }

    PRT_VISS_INFO("id: 0x%04x.\n", u8Tmp);

    if (u8Tmp != 0x9b) {
        PRT_VISS_ERR("ID wrong! (0x%04x != 0x9b)\n", u8Tmp);
        return EI_FAILURE;
    }

    return EI_SUCCESS;
}

/* The following functions can be modified as needed */

static int CAMERA_I2cInit(VISS_DEV dev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;
    int ret = EI_SUCCESS;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    ret = CAMERA_SetI2cInfo(dev);
    CAMERA_CHECK_SUCCESS(ret);

    ret = CAMERA_I2C_Reg_Ops(&pstSnsState->stI2cInfo);
    CAMERA_CHECK_SUCCESS(ret);

    return EI_SUCCESS;
}

static int CAMERA_I2cExit(VISS_DEV dev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_PowerUp(VISS_DEV VissDev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(VissDev, pstSnsState);

    CAMERA_SensorPowerUp(VissDev, pstSnsState);

    return 0;
}

static EI_S32 CAMERA_PowerDown(VISS_DEV VissDev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(VissDev, pstSnsState);

    CAMERA_SensorPowerDown(VissDev, pstSnsState);

    return 0;
}

static EI_S32 CAMERA_Init(VISS_DEV dev)
{
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret = EI_SUCCESS;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    PRT_VISS_INFO("%s writeRegList success", SNS_NAME);

    return s32Ret;
}

static void CAMERA_Exit(VISS_DEV dev)
{
    CAMERA_I2cExit(dev);

    return;
}
static EI_S32 CAMERA_Stream(VISS_DEV dev, EI_BOOL bOn)
{
    EI_U32 j;
    const SNS_TYPE_ATTR_S *pstSnsType;
    SNS_STATE_S *pstSnsState = EI_NULL;
    EI_S32 s32Ret = EI_SUCCESS;
    EI_U16 tmp = 0;
    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    if (bOn) {
        pstSnsType = pstSnsState->pstSnsAttr;
        for (j = 0; j < MAX_COF; j++) {
            s32Ret = pstSnsState->stI2cInfo.pfnwriteRegList(pstSnsState,
                    pstSnsType->astRegCfgs[j].pstRegs, pstSnsType->astRegCfgs[j].u32RegsCnt);
            if (s32Ret != EI_SUCCESS) {
                PRT_VISS_ERR("%s writeRegList err", SNS_NAME);
                return s32Ret;
            }
        }
#if 0
        //0x1a[0]=0, 0x25=0xff
        s32Ret = pstSnsState->stI2cInfo.pfnReadReg(pstSnsState, 0x1a, &tmp);

        tmp &= (~0x1);

        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x1a, tmp);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x25, 0xff);
#endif
        if (s32Ret != EI_SUCCESS) {
            PRT_VISS_ERR("CAMERA_Stream*******%d\n", bOn);
            return s32Ret;
        }
    } else {
        //0x1a[0]=1, 0x25=0x00
        s32Ret = pstSnsState->stI2cInfo.pfnReadReg(pstSnsState, 0x1a, &tmp);

        tmp |= (0x1);

        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x1a, tmp);
        s32Ret += pstSnsState->stI2cInfo.pfnWriteReg(pstSnsState, 0x25, 0x00);

        if (s32Ret != EI_SUCCESS) {
            PRT_VISS_ERR("CAMERA_Stream*******%d\n", bOn);
            return s32Ret;
        }
    }

    PRT_VISS_INFO("CAMERA_Stream*******%d\n", bOn);
    return EI_SUCCESS;
}

static EI_S32 CAMERA_SetImageMode(VISS_DEV dev, SNS_TYPE_E enSnsType)
{
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);
    CAMERA_CHECK_POINTER(pstSnsState);

    pstSnsState->enSnsType = enSnsType;
    pstSnsState->bSyncInit = EI_FALSE;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_EnumSnstype(VISS_DEV VissDev, EI_U32 u32Index, SNS_TYPE_E *peSnstype)
{
    const SNS_TYPE_ATTR_S *pstSnsType;

    if (u32Index >= ARRAY_SIZE(s_astSnsAttr))
        return EN_ERR_NO_FOUND;

    pstSnsType = &s_astSnsAttr[u32Index];

    *peSnstype = pstSnsType->enSnsType;

    return EI_SUCCESS;
}

static EI_S32 CAMERA_InitSensorExpFunction(SENSOR_EXP_FUNC_S *pstSensorExpFunc)
{
    CAMERA_CHECK_POINTER(pstSensorExpFunc);

    memset(pstSensorExpFunc, 0, sizeof(SENSOR_EXP_FUNC_S));

    pstSensorExpFunc->pfnSensorPowerUp  = CAMERA_PowerUp;
    pstSensorExpFunc->pfnSensorPowerDown = CAMERA_PowerDown;
    pstSensorExpFunc->pfnSensorDetect   = CAMERA_Detect;
    pstSensorExpFunc->pfnSensorInit     = CAMERA_Init;
    pstSensorExpFunc->pfnSensorStream   = CAMERA_Stream;
    pstSensorExpFunc->pfnSensorExit     = CAMERA_Exit;
    pstSensorExpFunc->pfnSensorSetImageMode   = CAMERA_SetImageMode;
    pstSensorExpFunc->pfnSensorEnumSnstype   = CAMERA_EnumSnstype;

    return EI_SUCCESS;
}

/****************************************************************************
 * callback structure                                                       *
 ****************************************************************************/

static EI_S32 CAMERA_CtxInit(VISS_DEV dev)
{
    SNS_STATE_S *pastSnsStateCtx = EI_NULL;

    SNS_GET_CTX(dev, pastSnsStateCtx);

    CAMERA_CHECK_POINTER(pastSnsStateCtx);

    memset(pastSnsStateCtx, 0, sizeof(SNS_STATE_S));

    pastSnsStateCtx->pstPowerUpAct      = s_stPowerUpAct;
    pastSnsStateCtx->pstPowerDownAct    = s_sPowerDownAct;
    pastSnsStateCtx->u8PwrUpActs        = ARRAY_SIZE(s_stPowerUpAct);
    pastSnsStateCtx->u8PwrDnActs        = ARRAY_SIZE(s_sPowerDownAct);

    return EI_SUCCESS;
}

static EI_VOID CAMERA_CtxExit(VISS_DEV dev)
{
    return ;
}

static EI_S32 CAMERA_RegisterVissCallback(VISS_DEV dev, SNS_TYPE_E enType)
{
    EI_S32 s32Ret;
    SENSOR_S stSns = {0};
    EI_U32 i;
    SNS_STATE_S *pstSnsState = EI_NULL;

    s32Ret = CAMERA_CtxInit(dev);
    if (EI_SUCCESS != s32Ret) {
        return EI_FAILURE;
    }

    SNS_GET_CTX(dev, pstSnsState);

    for (i = 0; i < ARRAY_SIZE(s_astSnsAttr); i++) {
        if (enType == s_astSnsAttr[i].enSnsType) {
            pstSnsState->pstSnsAttr = &s_astSnsAttr[i];
            break;
        }
    }

    pstSnsState->enSnsType = enType;
    pstSnsState->Dev = dev;

    if (i >= ARRAY_SIZE(s_astSnsAttr)) {
        PRT_VISS_ERR("%s does not support this chn configuration", SNS_NAME);
        return EI_FAILURE;
    }

    s32Ret = CAMERA_I2cInit(dev);
    if (EI_SUCCESS != s32Ret) {
        return EI_FAILURE;
    }

    stSns.stSnsAttrInfo.eSensorId = SNS_ID;
    stSns.stSnsAttrInfo.enDevType = DEV_TYPE;
    stSns.stSnsAttrInfo.pstSns = pstSnsState;

    s32Ret  = CAMERA_InitSensorExpFunction(&stSns.stSnsAttrInfo.stSnsExp);
    s32Ret |= VISS_SensorRegCallBack(dev, &stSns);
    if (EI_SUCCESS != s32Ret) {
        PRT_VISS_ERR("%s sensor register callback function failed!\n", SNS_NAME);
        return s32Ret;
    }

    s32Ret = CAMERA_OpenI2c(pstSnsState);
    CAMERA_CHECK_SUCCESS(s32Ret);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_UnregisterVissCallback(VISS_DEV dev)
{
    EI_S32 s32Ret;
    SNS_STATE_S *pstSnsState = EI_NULL;

    SNS_GET_CTX(dev, pstSnsState);

    s32Ret = CAMERA_ExitI2c(pstSnsState);
    CAMERA_CHECK_SUCCESS(s32Ret);

    s32Ret = VISS_SensorUnRegCallBack(dev, SNS_ID);
    if (EI_SUCCESS != s32Ret) {
        PRT_VISS_ERR("%s sensor unregister callback function failed!\n", SNS_NAME);
        return s32Ret;
    }

    CAMERA_CtxExit(dev);

    return EI_SUCCESS;
}

static EI_S32 CAMERA_GetVissDevAttrBySns(SNS_TYPE_E enType,
    VISS_DEV_ATTR_S *pstVissDevAttr)
{
    EI_U32 i;
    const SNS_TYPE_ATTR_S *pstSnsType;

    for (i = 0; i < ARRAY_SIZE(s_astSnsAttr); i++) {
        if (enType == s_astSnsAttr[i].enSnsType) {
            pstSnsType = &s_astSnsAttr[i];
            pstVissDevAttr->stSize          = pstSnsType->stSize;
            pstVissDevAttr->enWorkMode      = pstSnsType->enWorkMode;
            pstVissDevAttr->mClock          = pstSnsType->u32Mclock;
            pstVissDevAttr->enPixelFormat   = pstSnsType->enPixelFormat;
            pstVissDevAttr->enWdrMode       = pstSnsType->enWdrMode;
            pstVissDevAttr->enIspWdrMode    = pstSnsType->enIspWdrMode;
            pstVissDevAttr->enRgbSeq        = pstSnsType->enRgbSeq;
            pstVissDevAttr->u32ModuleClk    = pstSnsType->u32ModuleClk;
            pstVissDevAttr->u32Fps          = pstSnsType->u32FrameRate;
            pstVissDevAttr->u32IspClk       = pstSnsType->u32IspClk;
            pstVissDevAttr->u32IppuClk      = pstSnsType->u32IppuClk;
            pstVissDevAttr->pcSnsName       = SNS_NAME;
            pstVissDevAttr->stDevCfg        = pstSnsType->stDevCfg;
            return EI_SUCCESS;
        }
    }

    PRT_VISS_ERR("%s does not support this dev configuration", SNS_NAME);

    return EI_FAILURE;
}

static EI_S32 CAMERA_GetVissChnAttrBySns(SNS_TYPE_E enType,
    VISS_CHN_ATTR_S *pstVissChnAttr)
{
    EI_U32 i;
    const SNS_TYPE_ATTR_S *pstSnsType;

    for (i = 0; i < ARRAY_SIZE(s_astSnsAttr); i++) {
        if (enType == s_astSnsAttr[i].enSnsType) {
            pstSnsType = &s_astSnsAttr[i];
            pstVissChnAttr->stSize           = pstSnsType->stSize;
            pstVissChnAttr->enPixelFormat    = pstSnsType->enPixelFormat;
            pstVissChnAttr->stFrameRate.s32SrcFrameRate      = pstSnsType->u32FrameRate;
            return EI_SUCCESS;
        }
    }

    PRT_VISS_ERR("%s does not support this chn configuration", SNS_NAME);

    return EI_FAILURE;

}

CAMERA_OBJ_S stCameraGc0308dvpObj = {
    .pfnRegisterVissCallback    = CAMERA_RegisterVissCallback,
    .pfnUnRegisterVissCallback  = CAMERA_UnregisterVissCallback,
    .pfnRegisterIspCallback     = EI_NULL,
    .pfnUnRegisterIspCallback   = EI_NULL,
    .pfnGetVissDevAttrBySns     = CAMERA_GetVissDevAttrBySns,
    .pfnGetVissChnAttrBySns     = CAMERA_GetVissChnAttrBySns,
};


#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */

